package com.dede.state;

import android.app.Activity;
import android.support.v4.app.Fragment;
import android.view.View;

import com.dede.state.component.StateComponent;

import java.util.ArrayList;
import java.util.List;

/**
 * 单例的State管理类
 *
 * @author hsh
 *         2018/1/22 17:51.
 */
public final class State {

    private State() {
    }

    private static volatile State mInstance;
    private Builder builder;

    State setBuilder(Builder builder) {
        this.builder = builder;
        return this;
    }

    /**
     * 获取State单例
     *
     * @return
     */
    public static State getDefault() {
        if (mInstance == null) {
            synchronized (State.class) {
                if (mInstance == null) {
                    mInstance = new State();
                }
            }
        }
        return mInstance;
    }

    /**
     * 在Activity注册
     *
     * @param activity       Activity
     * @param reloadListener 重新加载监听
     * @return StateProxy
     */
    public StateProxy register(Activity activity, StateComponent.ReloadListener reloadListener) {
        TargetContent targetContent = StateUtil.findTargetContent(activity);
        return register(targetContent, reloadListener);
    }

    /**
     * 在Fragment注册
     *
     * @param fragment       Fragment
     * @param reloadListener 重新加载监听
     * @return StateProxy
     */
    public StateProxy register(Fragment fragment, StateComponent.ReloadListener reloadListener) {
        View view = fragment.getView();
        if (view == null) {
            throw new NullPointerException("register should be invoked after the Fragment's onCreateView.");
        }
        return register(view, reloadListener);
    }

    /**
     * 在Fragment注册
     *
     * @param fragment       Fragment
     * @param reloadListener 重新加载监听
     * @return StateProxy
     */
    public StateProxy register(android.app.Fragment fragment, StateComponent.ReloadListener reloadListener) {
        View view = fragment.getView();
        if (view == null) {
            throw new NullPointerException("register should be invoked after the Fragment's onCreateView.");
        }
        return register(view, reloadListener);
    }

    /**
     * 在View注册
     *
     * @param view           View
     * @param reloadListener 重新加载监听
     * @return StateProxy
     */
    public StateProxy register(View view, StateComponent.ReloadListener reloadListener) {
        TargetContent targetContent = StateUtil.findTargetContent(view);
        return register(targetContent, reloadListener);
    }

    /**
     * 所有的register方法最后都调用当前方法
     *
     * @param targetContent
     * @param reloadListener
     * @return
     */
    private StateProxy register(TargetContent targetContent, StateComponent.ReloadListener reloadListener) {
        return new StateProxy(
                targetContent,
                reloadListener,
                builder.componentList)
                .converter(builder.converter);
    }

    /**
     * 初始化Builder对象
     *
     * @return
     */
    public static Builder begin() {
        return new Builder();
    }

    /**
     * 通过Builder模式构建State对象
     */
    public static class Builder {

        List<StateComponent> componentList;
        private Converter converter;

        Builder() {
            componentList = new ArrayList<>();
        }

        /**
         * 添加新的状态
         *
         * @param component 状态组件
         * @return
         */
        public Builder addComponent(StateComponent component) {
            componentList.add(component);
            return this;
        }

        /**
         * 设置状态转换器
         * 可以根据不同的状态返回不同StateComponent，
         * 例如：
         * -1   ErrorComponent
         * 1    SuccessComponent
         * 0    EmptyComponent
         * ...
         *
         * @param converter
         * @return
         */
        public Builder converter(Converter converter) {
            this.converter = converter;
            return this;
        }

        public State builder() {
            return State.getDefault().setBuilder(this);
        }
    }
}
